package com.media.service.cameraPush;

import com.media.config.MediaCaptorLiveConfig;
import com.media.pojo.CameraPojo;
import com.media.common.ffmpeg.FFmpegError;
import com.media.common.ffmpeg.FFmpegUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Optional;

/**
 * hls 推流
 */
@Slf4j
public class CameraHlsPush implements CameraPush {

    /**
     * 设备信息
     */
    private CameraPojo cameraPojo;

    /**
     * 配置信息
     */
    private MediaCaptorLiveConfig mediaCaptorLiveConfig;


    private BufferedReader reader;
    /**
     * 当前开启的进程
     */
    private WeakReference<Process> currentProcess;

    /**
     * 提供获取进程的方法
     */
    @Override
    public WeakReference<Process> getCurrentProcess() {
        return currentProcess;
    }

    public CameraHlsPush(CameraPojo cameraPojo, MediaCaptorLiveConfig mediaCaptorLiveConfig) {
        this.cameraPojo = cameraPojo;
        this.mediaCaptorLiveConfig = mediaCaptorLiveConfig;
    }

    /**
     * RTSP 转换成 HLS
     */
    @Override
    public CameraHlsPush from() {
        try {
            String hlsToFile = mediaCaptorLiveConfig.getHlsPushPath() + "/" + cameraPojo.getToken() + ".m3u8";
            List<String> commend = FFmpegUtil.rtspToHls(cameraPojo.getRtsp(), hlsToFile);
            ProcessBuilder processBuilder = new ProcessBuilder(commend);
            Process process = processBuilder.start();
            currentProcess = new WeakReference<>(process);
            reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        } catch (Exception e) {
            log.error("RTSP 转 HLS , 出现异常 : {}", cameraPojo, e);
            return null;
        }
        return this;
    }

    /**
     * 开始输出
     */
    @Override
    public void go() {
        try {
            String line;
            while ((line = reader.readLine()) != null) {
                log.debug("ffmpeg input={}", line);
                for (String e : FFmpegError.getErrors()) {
                    if (Optional.of(line).filter(r -> r.contains(e)).isPresent()) {
                        log.debug("ffmpeg RTSP to HLS error={}", line);
                    }
                }
            }
        } catch (IOException ignored) {
            log.info("RTSP 转 HLS , 流已经关闭 : {}", cameraPojo);
        } catch (Exception e) {
            log.error("RTSP 转换 HLS  , 出现错误 : {}", cameraPojo, e);
        }
    }
}
